package com.mf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mf.basic.BasicKey;
import io.github.heollhai.common.entity.bo.PermissionBo;
import io.github.heollhai.common.entity.bo.RoleBo;
import io.github.heollhai.common.entity.bo.UserBo;
import io.github.heollhai.common.entity.security.dto.UserByRoleDto;
import io.github.heollhai.common.entity.vo.permissionTree.RouteVo;
import io.github.heollhai.common.entity.vo.user.UserVo;
import io.github.heollhai.common.config.exceptions.GraceException;
import io.github.heollhai.common.utils.*;
import io.github.heollhai.common.utils.tree.TreeUtils;
import com.mf.entity.request.serach.UserSearchRequest;
import com.mf.enums.ActionTypeEnum;
import com.mf.enums.GenderEnum;
import com.mf.mapper.PermissionMapper;
import com.mf.mapper.RoleMapper;
import com.mf.mapper.UserMapper;
import com.mf.service.IUserService;
import jakarta.annotation.Resource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户表 服务实现类
 *
 * @author mf
 * @since 2024-08-06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserBo> implements IUserService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private PermissionMapper permissionMapper;

    /**
     * 分页查询用户和对应角色
     */
    @Override
    public Page<UserVo> pageListUserAndRole(UserSearchRequest userSearchRequest) {
        Page<UserBo> page = new Page<>(userSearchRequest.getPageNum(), userSearchRequest.getPageSize());
        Page<UserBo> page1 = userMapper.pageListUserAndRole(page, userSearchRequest);
        return MybatisPlusUtils.changePageDataClass(page1, UserVo.class);
    }

    /**
     * 分页查询
     */
    @Override
    public Page<UserVo> pageList(UserSearchRequest userSearchRequest) {
        Page<UserBo> page = new Page<>(userSearchRequest.getPageNum(), userSearchRequest.getPageSize());

        LambdaQueryWrapper<UserBo> queryWrapper = new LambdaQueryWrapper<>();
        if (VerifyUtils.isNotEmpty(userSearchRequest.getKey())) {
            queryWrapper.or(wrapper -> wrapper
                    .eq(UserBo::getName, userSearchRequest.getKey())
                    .or()
                    .eq(UserBo::getAccount, userSearchRequest.getKey())
                    .or()
                    .eq(UserBo::getPhone, userSearchRequest.getKey())
                    .or()
                    .eq(UserBo::getEmail, userSearchRequest.getKey())
                    .or()
                    .eq(UserBo::getRemark, userSearchRequest.getKey())
            );
        }

        if (VerifyUtils.isNotEmpty(userSearchRequest.getStatus())) {
            queryWrapper.eq(UserBo::getStatus, userSearchRequest.getStatus());
        }

        Page<UserBo> page1 = userMapper.selectPage(page, queryWrapper);
        return MybatisPlusUtils.changePageDataClass(page1, UserVo.class);
    }

    /**
     * 注册
     */
    @Override
    public Integer register(UserBo userBo) {
        // 验证是否可以注册
        verifyIsRegister(userBo);
        userBo.setSale(CommonUtils.getRandomString(6));
        if (VerifyUtils.isNotEmpty(userBo.getId())) {
          return  userMapper.updateById(userBo);
        }
        return userMapper.insert(userBo);
    }

    /**
     * 验证填入信息是否可以注册
     */
    private void verifyIsRegister(UserBo userBo) {

//        // 验证性别
//        if (VerifyUtils.isNotEmpty(userBo.getGender()) && EnumUtils.existsInEnum(GenderEnum.class,
//                userBo.getGender())) {
//            GraceException.display("性别不合法");
//        }

        // 验证邮箱
        if (VerifyUtils.isNotEmpty(userBo.getEmail()) && RegularVerificationUtils.validateEmail(userBo.getEmail())) {
            GraceException.display("邮箱不合法");
        }

        // 验证手机号
        if (VerifyUtils.isNotEmpty(userBo.getPhone()) && RegularVerificationUtils.validatePhoneNumber(userBo.getPhone())) {
            GraceException.display("手机号不合法");
        }

        // 查询账号是否存在
        UserBo userBo1 = findByAccount(userBo.getAccount());
        if (VerifyUtils.isEmpty(userBo.getId())) {
            if (VerifyUtils.isNotEmpty(userBo1)) {
                GraceException.display("账号已存在");
            }
        }

    }

    /**
     * 根据账号查询用户信息
     */
    @Override
    public UserBo findByAccount(String account) {
        LambdaQueryWrapper<UserBo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBo::getAccount, account);
        return userMapper.selectOne(queryWrapper);
    }

    /**
     * 根据账号查询用户信息以及权限等信息
     */
    @Override
    public UserDetails loadUserByUsername(String account) {
        // 设置权限信息
        UserBo userBo = userMapper.selectUserByUserName(account);

        UserByRoleDto userByRoleDto = new UserByRoleDto();

        if (VerifyUtils.isEmpty(userBo)) {
            throw new UsernameNotFoundException(account);
        }
        // 设置用户信息
        userByRoleDto.setUserBo(userBo);
        userByRoleDto.setId(userBo.getId());

        if (VerifyUtils.isNotEmpty(userBo.getRoleList())) {
            List<Integer> roleIds = userBo.getRoleList().stream().map(RoleBo::getId).toList();


            boolean isAdministrators =
                    userBo.getRoleList().stream().anyMatch(role -> role.getName().equals(BasicKey.SUPER_ADMIN));

            // 查询权限信息
            List<PermissionBo> permissionBoList;

            if (!isAdministrators) {
                permissionBoList = roleMapper.selectRolePermissionByRoleIds(roleIds);
            } else {
                permissionBoList = permissionMapper.selectList(null);
            }

            // 设置需要拦截后端权限 api 集合
            userByRoleDto.setBackAuthUrls(permissionBoList.stream().map(PermissionBo::getApiUrl)
                    .filter(VerifyUtils::isNotEmpty)
                    .collect(Collectors.toSet()));

            // 设置角色
            userByRoleDto.setRoleList(userBo.getRoleList().stream().map(RoleBo::getName).toList());

            // 设置角色ID
            userByRoleDto.setRoleIdList(roleIds);

            // 所有web按钮权限集合
            List<String> webMenuPermissionList =
                    permissionBoList.stream().filter(s -> s.getActionType().equals(ActionTypeEnum.BUTTON.value))
                            .map(PermissionBo::getMetaRole)
                            .filter(VerifyUtils::isNotEmpty)
                            .toList();
            userByRoleDto.setButtonPermissionList(webMenuPermissionList);

            // 获取web菜单权限
            List<PermissionBo> webPermissionList =
                    permissionBoList.stream()
                            .filter(s ->
                                    s.getActionType().equals(ActionTypeEnum.MENU.value) ||
                                            s.getActionType().equals(ActionTypeEnum.MENU_PUBLIC.value)).toList();

            // 将表中的权限信息转换为前端需要的格式
            List<RouteVo> routeVo = new RouteVo().buildRouteList(webPermissionList);

            // 设置前端路由树形结构
            userByRoleDto.setFrontRoutes(TreeUtils.getRoot(routeVo));

        }
        return userByRoleDto;
    }


}
